<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        html,
        body {
            height: 100%;
        }
    </style>
</head>

<body>
    <script>
        // 一段连续操作中，每段时间只执行一次
        function throttle(fn, delay) {
            let timer = null
            return function () {
                let context = this
                let args = arguments
                if (!timer) { // 没有定时器添加一个新的
                    timer = setTimeout(() => {
                        // 保证fn中this的指向为dom，并且保留参数
                        fn.apply(context, args)
                        timer = null
                    }, delay)
                }
                // 有定时器等它执行完
            }
        }
        function foo() {
            console.log('+++', this);
        }
        function throttle(fn, delay) {
            let flag = false
            return function() {
                let context = this
                let args = arguments
                if(!flag) {
                    setTimeout(() => {
                        fn.apply(context, args)
                        flag = false
                    }, delay)
                    flag = true
                }
            }
        }
        // 时间戳实现
        function timeThrottle(func, wait) {
            let context, args
            let previous = 0
            return function() {
                context = this
                let now = +new Date()
                if(now - previous > wait) {
                    func.apply(context, args)
                    previous = now
                }
            }
        }
        function throttle2(func, delay) {
            let timer = null
            return function(...args) {
                let context = this
                if(!timer) {
                    timer = setTimeout(() => {
                        func.apply(context, args)
                        timer = null
                    }, delay)
                }
            }
        }
        function throttle3(fn, delay, immediate) {
            let timer = null
            return function(...args) {
                let isFirst = !timer
                let that = this
                if(isFirst && immediate) {
                    fn.call(that, args)
                }
                if(!timer) {
                    timer = setTimeout(() => {
                        timer = null
                    }, delay)
                }
            }
        }
        document.body.addEventListener('click', throttle3(foo, 2000, true))
    </script>
</body>

</html>